home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
pcc12d.zip
/
ISETUP.A
< prev
next >
Wrap
Text File
|
1989-06-21
|
7KB
|
354 lines
; ISETUP.A - Setup for C program execution on IBM PC.
; jumped to by first instruction to do C initilization.
; DS:0 is program segment prefix.
; SS is program DS.
; SS:0 is size of C initilized memory.
; SS:2 is size of uninitilized memory.
; EQUs define fields.
IBM EQU 21H ;IBM DOS INTERRUPT NUMBER
CI_CODE EQU 1
CO_CODE EQU 2
DIRECT_CODE EQU 6
DIRECT_INPUT EQU 7
VERSION EQU 30H
READ EQU 3FH
SETBLK EQU 4AH
TERMINATE EQU 4CH
BS EQU 8
TAB EQU 9
LF EQU 0AH
CR EQU 0DH
CONTS EQU 19
CONTX EQU 24
DSEG
PUBLIC _PCB_,_MSDOS2_ ;USED BY CHAIN
NE_MSG DB 'not enough memory',10
MEMFROM DW 0 ;FIRSE FREE BYTE IN DS
_PCB_ DW 0 ;_PCB_ SEGMENT REGISTER
_ORIGSP_ DW 0 ;STARTING SP. CAUTION: MUST FOLLOW
;_PCB_
_MSDOS2_ DB 0 ;1 IF VERSION 2.0 OR ABOVE
LASTCH DB 0
CURCH DB 0
PUBLIC ERRNO_
ERRNO_ RW 1 ;ERROR NUMBER
CSEG
PUBLIC _CSETUP,EXIT_,PUTCHAR_,GETCHAR_,PUTS_,MAIN_
; this is the actual entry point for a C88 program.
; the following initilization must take place before a program
; is actually called.
; 1) set SP to highest available byte.
; 2) set uninitilized storage to zero.
; 3) calculate argc and argv.
; 4) set DS to users data area.
; 5) call main(argc,argv).
; if program returns then goto exit.
; SET SP.
_CSETUP:
MOV SS:_PCB_,DS ;SAVE _PCB_ FOR EXIT CALL
MOV AX,[2] ;IBM PUTS TOTAL SYSTEM PARAGRAPHS HERE
MOV BX,SS ;CURRENT SS:SP MUST BE WITHIN AVAILABLE
SUB AX,BX ;PARAGRAPHS AVAILABLE FOR DATA
JBE NOT_ENOUGH
DEC AX ;PLAY IT SAFE
CMP AX,1000H ;IF OVER 64K THEN SET SP TO 64K
JC UNDER_64
MOV AX,0FFFH ;MAXIMUM STACK WITHOUT WRAP
UNDER_64:
MOV CL,4 ;TURN PARAGRAPH INTO BYTE
SHL AX,CL
CMP AX,SP ;SEE IF BIG ENOUGH
JC NOT_ENOUGH
MOV BX,SS:[0] ;IF SP IS INIT DATA+RESDATA+127 THEN MAKE MAX.
ADD BX,SS:[2]
ADD BX,127
CMP SP,BX ;WANT MAXIMUM ?
JNZ HAVE_SP ;NO, MUST HAVE HAS A -Snn OPTION OF BIND
MOV SP,AX ;HAVE A GOOD STACK
HAVE_SP:MOV SS:_ORIGSP_,SP ;REMEMBER STACK FOR EXEC
; REMEMBER VERSION NUMBER
MOV AH,VERSION ;CODE TO ASK FOR VERSION
INT IBM
CMP AL,2 ;IS IT 2 OR ABOVE ?
JB OLDVER
MOV SS:_MSDOS2_,1 ;TRUE IF VERSION 2 OR ABOVE
OLDVER:
; CALCULATE ARGC AND ARGV. THE COMMAND TAIL IS BETWEEN 129 AND
; 255. COMMNAD TAIL IN COPIED TO TOP OF STACK AND ARGV VECTOR
; IS PLACED UNDER IT. THE COMMAND NAME IS LAMENTABLY NULL.
MOV BYTE [255],CR ;DONT FALL OFF END IF INVALID
MOV BYTE [128],' ' ;DONT FALL OFF START EITHER (REPLACES LENGTH)
MOV CX,1 ;NUMBER OF ARGUMENTS. ALWAYS (NULL) COMMAND
MOV SI,-1 ;LENGTH OF ARGUMENTS.
; FIND SIZE OF TAIL
CMD_COUNT:
INC SI
MOV AL,[SI+129] ;NEXT COMMAND CHAR
CMP AL,CR ;CR OR LF IS END OF LINE
JZ END_COUNT
CMP AL,LF
JNZ CMD_COUNT
END_COUNT:
MOV AX,0 ;NEED ZERO AT END
PUSH AX
TEST SI,1 ;NEED WORD ALLIGNED STACK
JZ WORD_A
INC SP ;ODD NOW SO EVEN LATER
WORD_A: MOV DI,SP ;REMEMBER LOC OF ZERO
SUB SP,SI ;MAKE ROOM FOR TAIL
MOV BP,SP ;BP CAN ADDRESS NEW TAIL
NTAIL: DEC SI
CMP SI,-1 ;-1 WHEN DONE
JZ SAVE_ARGS
; A NON WHITE SPACE PRECEEDED BY WHITE MEANS ANOTHER ARGUMENT
MOV AL,[SI+129]
CMP AL,' ' ;SEE IF WHITE
JZ WHITE
CMP AL,TAB
JNZ NOT_WHITE
WHITE: MOV AL,0 ;SET WHITE TO NULL FOR END OF STRING
JMP STUFF
; IS PRECEEDING A WHITE?
NOT_WHITE:
CMP BYTE [SI+128],' '
JZ NEW_ARG
CMP BYTE [SI+128],TAB
JNZ STUFF
NEW_ARG:LEA BX,[BP+SI] ;STORE ARGV ELEMENT
PUSH BX
INC CX ;INCREMENT ARGC
STUFF: MOV [BP+SI],AL ;PUT TAIL CHAR ON STACK
JMP NTAIL
; SAVE A POINTER TO A ZERO FOR ARGV[0]
SAVE_ARGS:
PUSH DI
; SAVE ARGV AND ARGC
MOV BP,SP ;DONT PUSH SP AS 286 IS DIFFERENT
PUSH BP ;*ARGV[]
PUSH CX ;ARGC
; SET DS TO CORRECT VALUE
MOV AX,SS
MOV DS,AX
; INITILIZE UNINITILIZED MEMORY TO ZERO
MOV DI,[0] ;LENGTH OF INITILIZED MEMORY IS HERE
MOV CX,[2] ;LENGTH OF UNINITILIZED IS HERE
MOV ES,AX ;ES=DS
MOV AL,0 ;THE ZERO
CLD
REP STOSB
; REMEMBER LOW ADDRESS OF FREE MEMORY
ADD DI,2 ;MAKE WORD ALLIGNED
AND DI,0FFFEH
MOV MEMFROM,DI ;PUT AWAY FOR MEMORY CALL
; NOW READY FOR MAIN
CALL MAIN_ ;AND DO THE PROGRAM
; FALL INTO EXIT IF RETURN
MOV AL,0 ;SET RETURN CODE TO ZERO
JMP DOEXIT
; exit();
EXIT_: POP AX ;RETRIEVE RETURN CODE
POP AX
DOEXIT: ;IN DOS 2.0 USE CODE 4C TO TERMINATE
;AS THIS ALLOWS AN ERROR CODE
CMP _MSDOS2_,0 ;DOS 1.0 ?
JZ OLDEND
MOV AH,TERMINATE ;DOC 2.0 TERMINATE CODE
INT IBM
OLDEND: PUSH _PCB_ ;CREATE A LONG RETURN TO _PCB_:0
MOV AX,0
PUSH AX
LRET
NOT_ENOUGH:
MOV AX,&NE_MSG
PUSH AX
CALL PUTS_
ADD SP,2
MOV AL,2 ;ERROR EXIT
JMP DOEXIT
; charactor = getchar();
GETCHAR_:
CMP LASTCH,0 ;SAVED CHAR
JZ DOGC
GLAST: MOV AL,LASTCH ;RETURN LAST CHAR
MOV LASTCH,0
JMP GOTIN
DOGC: MOV AH,CI_CODE ;CODE FOR ECHOED INPUT
INT IBM ;DO THE CONSOLE READ
GOTIN: MOV AH,0 ;RETURN A WORD
CMP AL,26 ;CONTROL z ?
JZ READNFG
RET ;CHARACTER IS IN AL
READNFG:MOV AX,-1 ;-1 IF EOF
RET
; putchar(character);
PUTCHAR_:POP AX ;RETURN ADDRESS
POP DX ;DL IS CHARACTER
PUSH DX
PUSH AX
CMP DL,LF ;MUST CHANGE LF TO CR,LF
JNZ XCO
MOV DL,CR ;PRINT THE CR FIRST
CALL XCO
MOV DL,LF ;PUT THE LF BACK
XCO: MOV AH,CO_CODE
INT IBM ;DO THE WRITE
RET
; puts(string address);
PUTS_: POP AX ;RETURN ADDRESS
POP BX ;STRING ADDRESS
PUSH BX
PUSH AX
PS_LP: MOV AL,[BX] ;NEXT CHAR
OR AL,AL
JZ PS_END ;ZERO AT END OF STRING
PUSH BX
PUSH AX ;CHAR
CALL PUTCHAR_ ;LET PUTCHAR TURN LF INTO CR,LF
ADD SP,2
POP BX
INC BX ;STRING POINTER
JMP PS_LP
PS_END: RET
PUBLIC CI_, CO_, CSTS_
; charactor = ci();
CI_: CMP LASTCH,0 ;SAVED CHAR
JZ DOCI
MOV AL,LASTCH ;RETURN LAST CHAR
MOV LASTCH,0
MOV AH,0
RET
DOCI: MOV AH,DIRECT_INPUT ;CODE FOR DIRECT CONSOLE INPUT
INT IBM
MOV AH,0 ;MAKE AN INT
RET
; charactor or zero = csts();
CSTS_: MOV AH,DIRECT_CODE ;CODE FOR DIRECT CONSOLE IO
MOV DL,0FFH ;WANT A CHAR
INT IBM
MOV LASTCH,AL ;SAVE CHARACTER
MOV AH,0 ;MAKE AN INT
RET
; co(character);
CO_: POP AX ;RETURN ADDRESS
POP DX
PUSH DX
PUSH AX
MOV AH,DIRECT_CODE ;WANT A DIRECT CONSOLE OUTPUT
INT IBM
RET
; MEMORY MANAGEMENT FUNCTIONS: _MEMORY, _SHOWSP, _SETSP
PUBLIC _MEMORY_,_SETSP_,_SHOWSP_
_MEMORY_:MOV AX,MEMFROM ;ADDRESS OF FIRST FREE BYTE OF MEMORY
RET
_SHOWSP_:POP DX ;RETURN ADDRESS
MOV AX,SP ;RETURN SP VALUE TO USER
JMP DX
_SETSP_:
POP DX ;CHOP THE STACK - DANGEROUS OPERATION
POP BX ;NEW SP VALUE
CMP BP,SP ;ANY LOCALS
JNZ NOC
MOV BP,BX ;MUST MOVE THE BP TOO
NOC: MOV SP,BX
PUSH BX
JMP DX
; SEGMENT REGISTER FUNCTIONS: _SHOWDS, _SHOWCS, _SETDS
PUBLIC _SHOWDS_,_SHOWCS_,_SETDS_
_SHOWDS_:MOV AX,DS ;DS (AND SS) VALUE
RET
_SHOWCS_:MOV AX,CS ;CS VALUE
RET
_SETDS_:POP DX ;RETURN VALUE
POP DS ;NEW DS
PUSH DS
JMP DX ;RETURN
; OS CALL USED BY OPEN, CREAT ETC.
; VALUE=_OS(CODE,ARGUMENT);
PUBLIC _OS_
_OS_: PUSH BP
MOV BP,SP
MOV AH,[BP+4] ;IBM CODE
MOV DX,[BP+6] ;ARGUMENT POINTER
INT IBM
MOV AH,0 ;MAKE RETURN AN INTEGER
POP BP
RET